using DimensionsHelper.Common.Utils;
using DimensionsHelper.LanguageService.Symbols;
using DimensionsHelper.LanguageService.Syntax;

namespace DimensionsHelper.LanguageService;

public class AnalysisObjectTypeSignature : AnalysisStatementWithDomain
{
    internal AnalysisObjectTypeSignature(
        ObjectTypeSignature syntaxNode,
        NamedTypeSymbol objectSymbol,
        AnalysisNode? parent) :
        base(AnalysisBoundKinds.ObjectTypeSignature, syntaxNode, objectSymbol, parent)
    {
        Syntax = syntaxNode;
        IReadOnlyList<QualifiedName> inheritNames = syntaxNode.GetInheritQualifiedNames();
        inheritNames.ForEach(n =>
            Children.Add(AnalysisNodeFactory.QualifiedName(n, this, 
                AnalysisQualifiedNameFlags.InheritInterfaceName)));
        // Class
        if (syntaxNode.Is<ClassSignature>(SyntaxKinds.ClassSignature, out ClassSignature? classSignature))
        {
            // implements
            classSignature.GetImplementInterfaces().ForEach(name =>
                Children.Add(AnalysisNodeFactory.QualifiedName(name, this,
                    AnalysisQualifiedNameFlags.ImplementInterfaceName)));
            // Constants
            classSignature.GetConstants().ForEach(constant =>
                Children.Add(AnalysisNodeFactory.ConstantSignature(constant, this)));
        }

        // members
        syntaxNode.GetProperties().ForEach(p =>
            Children.Add(new AnalysisPropertySignature(p, this)));
        syntaxNode.GetMethods().ForEach(m =>
            Children.Add(new AnalysisMethodSignature(m, this)));
    }

    public override ObjectTypeSignature Syntax { get; }

    public override AnalysisBlock? Body => null;
}


public static partial class AnalysisNodeFactory
{
    /// <summary>
    /// 创建一个对象类型签名
    /// </summary>
    /// <param name="syntaxNode">原始语法节点</param>
    /// <param name="objectSymbol">类型符号</param>
    /// <param name="parent">父节点，可以忽略</param>
    public static AnalysisObjectTypeSignature ObjectTypeSignature(
        ObjectTypeSignature syntaxNode,
        NamedTypeSymbol objectSymbol,
        AnalysisNode? parent)
    {
        return new AnalysisObjectTypeSignature(syntaxNode, objectSymbol, parent);
    }
}